﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Reflection;
using Castle.Components.Validator;

namespace Common
{
    /// <summary>
    /// 设置web页面控件和model的值相互设置
    /// </summary>
    public static class WebHelper
    {
        //public static void SetModelValues(object model, TextBox tb)
        //{
        //    string intxt = tb.Text.Trim();
        //    if (intxt == "-" || intxt == "")
        //    {
        //        tb.Text = "";
        //    }
        //    else
        //    {
        //        SetModelValueTxt(model, tb);
        //    }
            
        //}
        /// <summary>
        /// Sets the web value.(设置文本框的值)
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="tb">The tb.</param>
        public static void SetControlValue(object model, Control tb)
        {
            if (tb == null)
            {
                return;
            }
            string name = tb.GetType().Name;
            switch (name)
            {
                case "TextBox":
                    SetControlValueTxt(model, tb);
                    break;
                case "DropDownList":
                    SetControlValueDdl(model, tb);
                    break;
                case "CheckBox":
                    SetControlValueChk(model, tb);
                    break;
                default:
                    throw new Exception("不支持的类型");
            }

        }

        private static void SetControlValueChk(object model, Control tb)
        {
            string prefix = "chk";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);
            string tempValue = PropertyHelper.GetString(model, name);
            bool value = false;
            if (tempValue == "1")
            {
                value = true;
            }

            PropertyHelper.SetProperty(tb, "Checked", value);
        }

        private static void SetControlValueDdl(object model, Control tb)
        {
            string prefix = "ddl";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);
            string tempValue = PropertyHelper.GetString(model, name);
            SetControlValueDdl(tb, tempValue);

        }

        public static void SetControlValueDdl(Control tb, string tempValue)
        {
            DropDownList ddl = tb as DropDownList;
            ListItem li = ddl.Items.FindByValue(tempValue);
            if (li != null)
            {
                ddl.SelectedIndex = -1;
                li.Selected = true;
            }
        }

        private static void SetControlValueTxt(object model, Control tb)
        {
            string prefix = "txt";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);
            string value = PropertyHelper.GetString(model, name);
            PropertyHelper.SetProperty(tb, "Text", value);
        }

        /// <summary>
        /// Sets the model value.(设置model的值)
        /// </summary>
        /// <param name="model">The model.</param>
        /// <param name="tb">The tb.</param>
        /// <returns></returns>
        public static void SetModelValue(object model, Control tb)
        {
            if (tb == null)
            {
                return;
            }
            string name = tb.GetType().Name;
            switch (name)
            {
                case "TextBox":
                    SetModelValueTxt(model, tb);
                    break;
                case "DropDownList":
                    SetModelValueDdl(model, tb);
                    break;
                case "CheckBox":
                    SetModelValueChk(model, tb);
                    break;
                default:
                    throw new Exception("不支持的类型");
            }


        }

        public static void SetModelValueChk(object model, Control tb)
        {
            string prefix = "chk";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);

            string tempvalue = PropertyHelper.GetString(tb, "Checked");
            string value = "0";
            if (tempvalue == "True")
            {
                value = "1";
            }
            PropertyHelper.SetProperty(model, name, value);
        }

        private static void SetModelValueDdl(object model, Control tb)
        {
            string prefix = "ddl";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);
            string value = PropertyHelper.GetString(tb, "SelectedValue");
            PropertyHelper.SetProperty(model, name, value);
        }

        private static void SetModelValueTxt(object model, Control tb)
        {
            string prefix = "txt";
            char[] startStr = prefix.ToCharArray();
            string name = tb.ID.TrimStart(startStr);
            string value = PropertyHelper.GetString(tb, "Text");
            PropertyHelper.SetProperty(model, name, value);
        }
        /// <summary>
        /// Gets the content place.(默认值为ContentPlaceHolder1)
        /// </summary>
        /// <returns></returns>
        public static Control GetContentPlace(Page p)
        {
            return GetContentPlace("ContentPlaceHolder1", p);
        }
        public static Control GetContentPlace(string name, Page p)
        {
            Control thisControl = p.Controls[0].FindControl(name);
            return thisControl;
        }
        #region MyRegion
        private static void SetWebControlAttributes(RunWhen run, Type modelType)
        {

            System.Web.UI.ControlCollection ccc = null;
            for (int i = 0; i < ccc.Count; i++)
            {
                System.Web.UI.Control con = ccc[i];
                if (con is System.Web.UI.WebControls.WebControl)
                {
                    System.Web.UI.WebControls.WebControl web = con as System.Web.UI.WebControls.WebControl;
                    SetWebControlAttribs(run, modelType, web);
                }
            }

        }

        /// <summary>
        /// Sets the web control attributes.
        /// </summary>
        /// <param name="run">The run.</param>
        /// <param name="modelType">Type of the model.</param>
        public static void SetWebControlAttributes(RunWhen run, Type modelType, ControlCollection ccc)
        {


            for (int i = 0; i < ccc.Count; i++)
            {
                System.Web.UI.Control con = ccc[i];
                if (con is System.Web.UI.WebControls.WebControl)
                {
                    System.Web.UI.WebControls.WebControl web = con as System.Web.UI.WebControls.WebControl;
                    SetWebControlAttribs(run, modelType, web);
                }
            }

        }
        /// <summary>
        /// Sets the web control attribs.(设置web端客户端控件属性)
        /// </summary>
        /// <param name="run">The run.</param>
        /// <param name="modelType">Type of the model.</param>
        /// <param name="web">The web.</param>
        private static void SetWebControlAttribs(RunWhen run, Type modelType, System.Web.UI.WebControls.WebControl web)
        {
            string txt = web.ID;
            if (txt.StartsWith("txt"))
            {
                txt = txt.Substring(3);
            }

            PropertyInfo propertyInfo = modelType.GetProperty(txt);
            if (propertyInfo == null)
            {
                return;
            }
            string nameSpace = GetBusinessName(modelType);
            string checkType = propertyInfo.PropertyType.Name;

            if (checkType == "Nullable`1")
            {
                checkType = GetNullableTypeName(propertyInfo.PropertyType.FullName);
            }
            checkType = checkType.ToLower();
            bool isApp = false;
            object[] attributes = propertyInfo.GetCustomAttributes(typeof(AbstractValidationAttribute), false);
            for (int i = 0; i < attributes.Length; i++)
            {


                Castle.Components.Validator.AbstractValidationAttribute attr = (AbstractValidationAttribute)attributes[i];
                if (!(attr.RunWhen == run || attr.RunWhen == RunWhen.Everytime))
                {
                    continue;
                }
                Castle.Components.Validator.IValidator validator = attr.Build();
                if (validator is LengthValidator)//验证长度
                {
                    LengthValidator a = validator as LengthValidator;
                    web.Attributes.Add("minLength", a.MinLength.ToString());
                    if (web is System.Web.UI.WebControls.TextBox)
                    {
                        System.Web.UI.WebControls.TextBox txtbox = web as System.Web.UI.WebControls.TextBox;
                        txtbox.MaxLength = a.MaxLength;
                    }
                    isApp = true;

                }
                else if (validator is Castle.Components.Validator.RangeValidator)//验证范围
                {
                    Castle.Components.Validator.RangeValidator a = validator as Castle.Components.Validator.RangeValidator;
                    web.Attributes.Add("minValue", GetRangeValidatorMin(a));
                    web.Attributes.Add("maxValue", GetRangeValidatorMax(a));
                    isApp = true;
                }
                else if (validator is NonEmptyValidator)//不为空
                {
                    web.Attributes.Add("isEmptyEnable", "0");
                    isApp = true;
                }
                else if (validator is Castle.Components.Validator.RegularExpressionValidator)//如果应用正则表达式验证,custom消息取正则表达式的信息
                {
                    Castle.Components.Validator.RegularExpressionValidator a = validator as Castle.Components.Validator.RegularExpressionValidator;
                    web.Attributes.Add("customRegex", a.Expression);
                    web.Attributes.Add("customMsg", a.ErrorMessage);
                    isApp = true;
                }
                else if (validator is Castle.ActiveRecord.Framework.Validators.IsUniqueValidator)
                {
                    Castle.ActiveRecord.Framework.Validators.IsUniqueValidator a = validator as Castle.ActiveRecord.Framework.Validators.IsUniqueValidator;

                    if (!IsHaveAttr(web.Attributes.Keys, "customMethod"))
                    {   //添加自定义属性后要自己把IsUnique添加进去,
                        //例如,web控件加入customMethod="custom"
                        //Hack:自定义的紧紧是对客户端UI更友好,重要的验证服务端也要做

                        //       function custom(tag, nameSpace) {
                        //        var str = eval("regexEnum.intege1");//得到验证表达式
                        //        if (!$("#" + tag).val().match(str)) {
                        //            return "表达式错误";
                        //         }
                        //        if ($("#" + tag).val() == "aaa") {
                        //            return "出错了啊";
                        //        }
                        //        return IsUnique(tag, nameSpace);
                        //    }
                        web.Attributes.Add("customMethod", "IsUnique");
                    }

                    web.Attributes.Add("nameSpace", nameSpace);
                    isApp = true;
                }



            }
            if (isApp)
            {
                web.Attributes.Add("checkType", checkType);
            }
        }

        private static bool IsHaveAttr(System.Collections.ICollection keys, string attrName)
        {

            foreach (string item in keys)
            {
                if (item == attrName)
                {
                    return true;
                }
            }
            return false;
        }

        private static string GetBusinessName(Type modelType)
        {
            string str = modelType.FullName;
            String[] strs = str.Split('.');
            strs[1] = "Business";
            //TODO:测试
            for (int i = 0; i < strs.Length - 1; i++)
            {
                strs[i] += ".";
            }
            int intModel = strs.Length - 1;
            string strModel = strs[intModel];
            strModel = strModel.Remove(0, 1).Insert(0, "B");
            strs[intModel] = strModel;

            return string.Concat(strs);
        }
        private static string GetNullableTypeName(string p)
        {
            string regex = "(?<=System.Nullable`1..System.).+?(?=,)";
            System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Multiline)
                        | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(regex, options);
            System.Text.RegularExpressions.Match m = reg.Match(p);
            string strName = m.Value;
            return strName;
        }
        private static string GetRangeValidatorMax(Castle.Components.Validator.RangeValidator a)
        {
            FieldInfo fileInfo = GetFieldInfo(a, "max");
            return GetFieldInfoValue(a, fileInfo);
        }
        private static string GetRangeValidatorMin(Castle.Components.Validator.RangeValidator a)
        {
            FieldInfo fileInfo = GetFieldInfo(a, "min");
            return GetFieldInfoValue(a, fileInfo);
        }

        /// <summary>
        /// Gets the field info value.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="fileInfo">The file info.</param>
        /// <returns></returns>
        private static string GetFieldInfoValue(Castle.Components.Validator.RangeValidator a, FieldInfo fileInfo)
        {
            if (fileInfo == null)
            {
                return "";
            }
            return fileInfo.GetValue(a).ToString();
        }

        /// <summary>
        /// Gets the field.
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <returns></returns>
        private static FieldInfo GetFieldInfo(object o, string fieldName)
        {
            BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
            return GetFieldInfo(o, fieldName, bf);
        }
        /// <summary>
        /// Gets the field info.
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="fieldName">Name of the field.</param>
        /// <param name="bf">The bf.</param>
        /// <returns></returns>
        private static FieldInfo GetFieldInfo(object o, string fieldName, BindingFlags bf)
        {
            if (o == null)
            {
                return null;
            }
            return o.GetType().GetField(fieldName, bf);
        }
        #endregion
        /// <summary>
        /// Gets the controls in master.(应用母版页的时候返回本页的控件集合)
        /// </summary>
        /// <param name="page">The page.</param>
        /// <returns></returns>
        public static ControlCollection GetControlsInMaster(Page page)
        {
            return page.Controls[0].FindControl("form1").Controls[0].Controls;
        }
    }
}
